﻿using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Host.JWT
{
    /// <summary>
    /// ABP的加密算法
    /// </summary>
    public class AbpCipherAlgorithm
    {
        //默认盐
        private static byte[] DefaultSalt { get; set; }
        //默认密码短语
        private static string DefaultPassPhrase { get; set; }
        //默认初始字节
        private static byte[] DefaultInitVectorBytes { get; set; }

        /// <summary>
        /// 从配置文件读取配置
        /// </summary>
        /// <param name="configuration"></param>
        public static void Configure(IConfiguration configuration)
        {
            DefaultSalt = Encoding.ASCII.GetBytes(configuration["Cipher:Salt"]);
            DefaultPassPhrase = configuration["Cipher:Phrase"];
            DefaultInitVectorBytes = Encoding.ASCII.GetBytes(configuration["Cipher:Vector"]);
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="plainText"></param>
        /// <returns></returns>
        public static string Encrypt(string plainText)
        {
            if (string.IsNullOrEmpty(plainText)) return null;

            byte[] bytes = Encoding.UTF8.GetBytes(plainText);
            using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(DefaultPassPhrase, DefaultSalt))
            {
                byte[] bytes2 = rfc2898DeriveBytes.GetBytes(256 / 8);
                using (Aes aes = Aes.Create())
                {
                    aes.Mode = CipherMode.CBC;
                    using (ICryptoTransform transform = aes.CreateEncryptor(bytes2, DefaultInitVectorBytes))
                    {
                        using (MemoryStream memoryStream = new MemoryStream())
                        {
                            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
                            {
                                cryptoStream.Write(bytes, 0, bytes.Length);
                                cryptoStream.FlushFinalBlock();
                                return Convert.ToBase64String(memoryStream.ToArray());
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="cipherText"></param>
        /// <returns></returns>
        public static string Decrypt(string cipherText)
        {
            if (string.IsNullOrEmpty(cipherText)) return null;

            byte[] array = Convert.FromBase64String(cipherText);
            using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(DefaultPassPhrase, DefaultSalt))
            {
                byte[] bytes = rfc2898DeriveBytes.GetBytes(256 / 8);
                using (Aes aes = Aes.Create())
                {
                    aes.Mode = CipherMode.CBC;
                    using (ICryptoTransform transform = aes.CreateDecryptor(bytes, DefaultInitVectorBytes))
                    {
                        using (MemoryStream stream = new MemoryStream(array))
                        {
                            using (CryptoStream cryptoStream = new CryptoStream(stream, transform, CryptoStreamMode.Read))
                            {
                                byte[] array2 = new byte[array.Length];
                                int count = cryptoStream.Read(array2, 0, array2.Length);
                                return Encoding.UTF8.GetString(array2, 0, count);
                            }
                        }
                    }
                }
            }
        }
    }
}
